<?php
namespace org\copperforest\oak\resources;
use \org\copperforest\oak\resources\configuration as configuration;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of ControledResponse
 *
 * @author agama
 */
class ResponseNode extends Response
{
    static protected $extension;
    
    protected $templatePath;
    protected $configuration;
    protected $backtrace;
    protected $hRef;
    public $uniqId;
    
    public $GET;
    
    
    function __construct()
    {
        parent::__construct();
        
        $this->templatePath = CF_CLASS_PATH . strtr(  $this->className,
            array( '\\' => DIRECTORY_SEPARATOR ) ) . '.';
    }

    
    function evalueAndFetch()
    {
    }
    
    public function setConfiguration( configuration\AbstractConfiguration $configuration )
    {
        $this->configuration = $configuration;
        $this->backtrace = $configuration->backtrace;
        $this->uniqId = $this->backtrace[ 0 ]->uniqId;
        $this->hRef = CF_HTTP_PATH . $this->backtrace[ 0 ]->relativeReference;
          
        if( isset( $_GET[ $this->uniqId ] ) ){
            $this->GET = $_GET[ $this->uniqId ];
        }
        
        $this->evalueAndFetch();
    }
    
    public function getResponse( $relativeReference )
    {
        $responseConfiguration = $this->configuration->fetch( $relativeReference );
        return  $responseConfiguration->getResponse(); //esto ya podría establecer el configuratio
    }
       
    function __toString()
    {
        if( file_exists( $this->templatePath . self::$extension . '.php' ) ){
            include $this->templatePath . self::$extension . '.php';
        }
        
        return "";
    }
    
    //used only in ground template
    function plantRoot( $extension )
    {
        self::$extension = $extension;
        return $this->__toString();
    }


    function stampForm( $action )
    {

        return '<input type="hidden" name="oak_action" value="' . htmlspecialchars( $action ).'" />'.
               '<input type="hidden" name="oak_csrf_token" value="' . htmlspecialchars( $_SESSION->getCsrfToken() ) . '" />';
        //En caso de que sea por ajax
        //
        //Aqui tendría que poner la traza, para reconstruirla en le POST
    }
   
    function doPost( $action )
    {   
        //Ahora si hay campos indicando que había files y se enviaron
        if( $action == 'oak_upload_file' ) {
            
            if( !$_SESSION->temporalExists() ) {
                $_SESSION->mkdirTemporal();
            }
            
            $temporalDirectory =  CF_TEMP_PATH . $_SESSION->getId() . DIRECTORY_SEPARATOR . $this->backtrace[ 0 ]->uniqId .  DIRECTORY_SEPARATOR;
            
            if( !file_exists( $temporalDirectory ) ){
                mkdir( $temporalDirectory, 0777 );
                chmod( $temporalDirectory, 0777 );
            }

            //Puedo guardarlo con un uniqId y guardar en sesion información de los archivos temporales
            do{
                $id = generateUniqueId();
            }
            while( file_exists( $temporalDirectory . $id ) );

            if( !isset( $_SESSION[ 'OAK_FILES' ] ) ) {
                $_SESSION[ 'OAK_FILES' ] = array();
            }

            if( !isset( $_SESSION[ 'OAK_FILES' ][ $_POST[ 'joak_action' ] ] ) ){
                $_SESSION[ 'OAK_FILES' ][ $_POST[ 'joak_action' ] ] = array();
            }
            
            $_SESSION[ 'OAK_FILES' ][ $_POST[ 'joak_action' ] ][ $id ] = array(
                //the javascript function may set this input in the iframe form 
                'input' => $_POST[ 'input_name' ],
                'index' => $_POST[ 'input_index' ],
                
                'name' => $_FILES[ 'FILE' ]['name'],
                'tmp_name' => $temporalDirectory . $id,
                'size' => $_FILES[ 'FILE' ]['size'],
                'type' => $_FILES[ 'FILE' ]['type']
            );

             //$file = $this->tmpPrefix . $inputname;
             move_uploaded_file( $_FILES[ 'FILE' ][ 'tmp_name' ], $temporalDirectory . $id );    
        }
        else if( !empty( $_SESSION[ 'OAK_FILES' ][ $action ] ) ) {
            
            $queryString = '';
            foreach( $_SESSION[ 'OAK_FILES' ][ $action ] as $id => $fileDescriptor ){
                $queryString .= urlencode( $fileDescriptor[ 'input_name' ] ) . '=' . urlencode( $id );
            }
            
            $files = null;
            parse_str( $queryString, $files );
            //Ahora tengo una representación de los arrays de files que se hubiesen creado
            //pero el array de files es un tanto peculiar
            foreach( $files as $nameInFiles => $arrayOrId ){
                
                if( is_array( $arrayOrId ) ){
                    
                    $_FILES[ $nameInFiles ] [ 'name' ] = $arrayOrId;
                    $_FILES[ $nameInFiles ] [ 'tmp_name' ] = $arrayOrId;
                    $_FILES[ $nameInFiles ] [ 'type' ] = $arrayOrId;
                    $_FILES[ $nameInFiles ] [ 'size' ] = $arrayOrId;
                    
                    self::parseArrayToFiles( $_FILES[ $nameInFiles ] [ 'name' ], $action,  'name' );
                    self::parseArrayToFiles( $_FILES[ $nameInFiles ] [ 'tmp_name' ], $action,  'tmp_name' );
                    self::parseArrayToFiles( $_FILES[ $nameInFiles ] [ 'type' ], $action,  'type' );
                    self::parseArrayToFiles( $_FILES[ $nameInFiles ] [ 'size' ], $action,  'size' );
                    
                }
                else{
                    
                    $fileDescriptor = $_SESSION[ 'OAK_FILES' ][ $action ] [ $arrayOrId ];
                    
                    $_FILES[ $nameInFiles ] [ 'name' ] = $fileDescriptor[ 'name' ];
                    $_FILES[ $nameInFiles ] [ 'tmp_name' ] = $fileDescriptor[ 'tmp_name' ];
                    $_FILES[ $nameInFiles ] [ 'type' ] = $fileDescriptor[ 'type' ];
                    $_FILES[ $nameInFiles ] [ 'size' ] = $fileDescriptor[ 'size' ];
                    
                }
            }
            
            //Aqui tengo que recuperar los archivos y meterlos en FILE, El problema lo tenemos con el name de los input file
                
            unset( $_SESSION[ 'OAK_FILES' ][ $action  ] );
        }
    }
    
    static private function parseArrayToFiles( &$array, $action, $field ){
        foreach( $array as $key=>$value ){
            if( is_array( $value ) ){
                self::parseArrayToFiles( $value, $action, $field );
            }
            else{
                $array[ $key ] = $_SESSION[ 'OAK_FILES' ][ $action ] [ $value ][ $field ];
            }
        }
    }

    static private function scanFolder( $path, &$classes, $len = null )
    {
        if ( $len == null ) {
            $len = strlen( $path );
        }

        $ground = str_replace( DIRECTORY_SEPARATOR, '\\',
                substr( $path, $len, -1 ) );


        $files = array_diff( scandir( CF_CLASS_PATH ), array( '.', '..' ) );

        foreach ( $files as $f ) {

            if ( is_dir( $path . $f ) ) {
                self::scanFolder( $path . $f . DIRECTORY_SEPARATOR, $classes,
                        $len );
            } else {
                $matches = array( );

                if ( preg_match( '/^(.+).class.php$/', $f, $matches ) ) {

                    if ( is_subclass( $ground . $matches[ 1 ],
                                    '\org\copperforest\oak\resources\ResponseNode' ) && !isset( $classes[ $ground . $matches[ 1 ] ] ) )
                            $classes[ $ground . $matches[ 1 ] ] = array( );
                }
                else if ( preg_match( '/^(.+)\.([^\.]+).php$/', $f, $matches ) ) {

                    if ( is_subclass( $ground . $matches[ 1 ],
                                    '\org\copperforest\oak\resources\ResponseNode' ) ) {

                        if ( !isset( $GLOBALS[ 'classes' ][ $ground . $matches[ 1 ] ] ) )
                                $classes[ $ground . $matches[ 1 ] ] = array( );

                        $classes[ $ground . $matches[ 1 ] ][ $matches[ 2 ] ] = true;
                    }
                }
            }
        }
    }

    //TIENE QUE HACER UN DEPLOY COPIANDO LAS PLANTILLAS PARA QUE LAS HEREDEN LAS HIJAS
    static function build()
    {
        //Aqui tb puedo identificar los archivos js y css

        $classes = array( );

        self::scanFolder( CF_CLASS_PATH, $classes );

        foreach ( $classes as $c => &$templates ) {
            $class = $c;

            while ( ( $class = get_parent_class( $class ) ) != null ) {

                if ( isset( $classes[ $class ] ) ) {

                    foreach ( $classes[ $class ] as $t => $true ) {
                        if ( !isset( $templates[ $t ] ) ) {

                            $templates[ $t ] = true;
                            copy( CF_CLASS_PATH . str_replace( '\\',
                                            DIRECTORY_SEPARATOR, $class ) . '.' . $t . '.php',
                                    CF_CLASS_PATH . str_replace( '\\',
                                            DIRECTORY_SEPARATOR, $c ) . '.' . $t . '.php' );
                        }
                    }
                }
            }
        }
    }
    

}